/**
 * Copyright (c) 2015-2016, Javen Zhou  (javenlife@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.sxyc.weixin.controller;

import java.util.HashMap;
import java.util.Map;

import com.jfinal.kit.HttpKit;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.weixin.sdk.api.ApiConfig;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.CustomServiceApi;
import com.jfinal.weixin.sdk.api.PaymentApi;
import com.jfinal.weixin.sdk.api.PaymentApi.TradeType;
import com.jfinal.weixin.sdk.api.SnsAccessToken;
import com.jfinal.weixin.sdk.api.SnsAccessTokenApi;
import com.jfinal.weixin.sdk.jfinal.ApiController;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.jfinal.weixin.sdk.utils.JsonUtils;
import com.sxyc.tintin.model.Chongzhi;
import com.sxyc.tintin.model.Device;
import com.sxyc.tintin.model.DeviceBinding;
import com.sxyc.utils.ResultUtils;
import com.sxyc.utils.WeixinUtil;
import com.sxyc.weixin.m2m.TerminalDetailsService;

/**
 * 感谢 *半杯* 童鞋联调支付API
 * @author L.cm
 */
public class WeixinPayController extends ApiController {
	

	@Override
	public ApiConfig getApiConfig() {
		// TODO Auto-generated method stub
		return WeixinUtil.getApiConfig();
	}

	//商户相关资料
	private static String appid = "wx7f007a162601553b";
	private static String secret = "15ec1785581da548e1ec10d0a39c1026";
	private static String partner = "1437295602";
	private static String paternerKey = "a1b2c3d4e5f6g7h8i9j11k12l13m14nl";
	private static String notify_url = PropKit.get("domain")+"/pay/pay_notify";
	
	
	/**
	 * 终端充值配置
	 */
	public void tochongzhi(){
		int price = 4900;
		String iccid = getPara("iccid");
		if(getPara("price") != null){
			price = getParaToInt("price");
		}
		getRequest().getSession().setAttribute("price", price);
		getRequest().getSession().setAttribute("iccid", iccid);
		//网页授权
		if(iccid != null){
			String url = SnsAccessTokenApi.getAuthorizeURL(PropKit.get("appId"), PropKit.get("domain")+"/pay/chongzhi", true);
			
			redirect(url);
			return;
		}
		renderText("iccid 为空，请重试！");
	}
	
	/**
	 * 充值配置
	 */
	public void chongzhi() {
		String code = getPara("code");
		SnsAccessToken accessToken = SnsAccessTokenApi.getSnsAccessToken(getApiConfig().getAppId(), getApiConfig().getAppSecret(),code);
		String openId = accessToken.getOpenid();
		System.out.println("openId---------->"+openId);
		getRequest().getSession().setAttribute("openId", openId);
		DeviceBinding user = DeviceBinding.dao.getWxUserByOpenId(openId);
		System.out.println("user------>"+user);
		if(user==null){
			renderJsp("bind.jsp");
		}else{
		Device device=Device.dao.getDevice(user.get("DeviceId"));
		this.setAttr("device",device);
		this.setAttr("openId",openId);
		
		String iccid = (String) getRequest().getSession().getAttribute("iccid");
		TerminalDetailsService service = new TerminalDetailsService();
		Map<String, String> map = service.getDetails(iccid);
		if(map == null){
			render("/wx/html/error.html");
			return;
		}
		setAttr("detail", map);
		setAttr("chongzhi", service.chongzhi(iccid));
		render("terminalchongzhi.jsp");
		}

	}
	
	/**
	 * 甲客微信充值配置
	 */
	public void wxchongzhi(){
		// 用户同意授权，获取code
		String code = getPara("code");
		String openId = (String) getRequest().getSession().getAttribute("openId");
		if(openId == null && code == null){
			String url = SnsAccessTokenApi.getAuthorizeURL(getApiConfig().getAppId(),PropKit.get("domain")+"/pay/wxchongzhi", false);
			redirect(url);
		}else{
			if(openId==null){
				SnsAccessToken accessToken = SnsAccessTokenApi.getSnsAccessToken(getApiConfig().getAppId(), getApiConfig().getAppSecret(),code);
				openId = accessToken.getOpenid();
				getRequest().getSession().setAttribute("openId", openId);
			}
			DeviceBinding user = DeviceBinding.dao.getWxUserByOpenId(openId);
			if(user==null){
				renderJsp("bind.jsp");
			}else{
				Device device=Device.dao.getDevice(user.get("DeviceId"));
				this.setAttr("device",device);
				this.setAttr("openId",openId);
				
				String iccid = device.getStr("ICCID");
				System.out.println("iccid : "+iccid);
				TerminalDetailsService service = new TerminalDetailsService();
				Map<String, String> map = service.getDetails(iccid);
				if(map == null){
					render("/wx/html/error.html");
					return;
				}
				setAttr("detail", map);
				setAttr("chongzhi", service.chongzhi(iccid));
				render("chongzhi.jsp");
			}
		}
	}
	
	public void oilchongzhi(){
		String code = getPara("code");
    	String openId = (String) getRequest().getSession().getAttribute("openId");
    	if(openId == null && code == null){
			String url = SnsAccessTokenApi.getAuthorizeURL(PropKit.get("appId"), PropKit.get("domain")+"/pay/oilchongzhi", true);
			redirect(url);
		}else{
			SnsAccessToken accessToken = SnsAccessTokenApi.getSnsAccessToken(getApiConfig().getAppId(), getApiConfig().getAppSecret(),code);
			openId = accessToken.getOpenid();
			getRequest().getSession().setAttribute("openId", openId);
			render("oilchongzhi.jsp");
		}
	}
	
	public void oils(){
		getRequest().getSession().setAttribute("rice", getParaToInt("rice"));
		getRequest().getSession().setAttribute("phone", getPara("phone"));
		getRequest().getSession().setAttribute("cardnum", getPara("cardnum"));
		renderJson(ResultUtils.getSuccessResult());
	}
	
	/**
	 * 流量充值
	 */
	public void pay() {
		// openId，采用 网页授权获取 access_token API：SnsAccessTokenApi获取
		String code = getPara("code");
		String res = CacheKit.get("code", code);
		if (res == null) {
			CacheKit.put("code", code, "1");
		}else{
			LogKit.warn("code 去重！");
			return;
		}
		if(!code.equals("") || code != null){
			SnsAccessToken accessToken = SnsAccessTokenApi.getSnsAccessToken(appid, secret,code);
			String openId = accessToken.getOpenid();
			System.out.println("openid2 : "+openId);
			String openid = (String) getRequest().getSession().getAttribute("openId");
			
			String out_trade_no = WeixinUtil.genOutTradNo("sim");
			Map<String, String> params = new HashMap<String, String>();
			params.put("appid", appid);
			params.put("mch_id", partner);
			params.put("body", "流量充值");
			params.put("out_trade_no", out_trade_no);
			params.put("total_fee", 4900 + "");
			
			String ip = IpKit.getRealIp(getRequest());
			if (StrKit.isBlank(ip)) {
				ip = "127.0.0.1";
			}
			
			params.put("spbill_create_ip", ip);
			params.put("trade_type", TradeType.JSAPI.name());
			params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
			params.put("notify_url", notify_url);
			params.put("openid", openId);
	
			String sign = PaymentKit.createSign(params, paternerKey);
			params.put("sign", sign);
			String xmlResult = PaymentApi.pushOrder(params);
			
//			System.out.println(xmlResult);
			Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
			
			String return_code = result.get("return_code");
			String return_msg = result.get("return_msg");
			if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
				renderText(return_msg);
				return;
			}
			String result_code = result.get("result_code");
			if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
				renderText(return_msg);
				return;
			}
			// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
			String prepay_id = result.get("prepay_id");
			
			Map<String, String> packageParams = new HashMap<String, String>();
			packageParams.put("appId", appid);
			packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
			packageParams.put("nonceStr", System.currentTimeMillis() + "");
			packageParams.put("package", "prepay_id=" + prepay_id);
			packageParams.put("signType", "MD5");
			String packageSign = PaymentKit.createSign(packageParams, paternerKey);
			packageParams.put("paySign", packageSign);
			
			String iccid = (String) getRequest().getSession().getAttribute("iccid");
			new Chongzhi().set("iccid", iccid)
							.set("price", 4900)
							.set("openid", openId)
							.set("openid2", openid)
							.set("outTradeNo", out_trade_no)
							.save();
			String jsonStr = JsonUtils.toJson(packageParams);
			setAttr("json", jsonStr);
			render("pay.jsp");
		}
	}
	
	/**
	 * 油卡充值
	 */
	public void oilPay() {
		// openId，采用 网页授权获取 access_token API：SnsAccessTokenApi获取
		String code = getPara("code");
		String res = CacheKit.get("code", code);
		if (res == null) {
			CacheKit.put("code", code, "1");
		}else{
			LogKit.warn("code 去重！");
			return;
		}
		if(!code.equals("") || code != null){
			SnsAccessToken accessToken = SnsAccessTokenApi.getSnsAccessToken(appid, secret,code);
			String openId = accessToken.getOpenid();
//			System.out.println("openid2 : "+openId);
			String openid = (String) getRequest().getSession().getAttribute("openId");
			
			int price = (int) getRequest().getSession().getAttribute("price");
			String out_trade_no = WeixinUtil.genOutTradNo("oil"+price);
			Map<String, String> params = new HashMap<String, String>();
			params.put("appid", appid);
			params.put("mch_id", partner);
			params.put("body", "油卡充值");
			params.put("out_trade_no", out_trade_no);
			params.put("total_fee", price + "");//微信充值以分为单位
			
			String ip = IpKit.getRealIp(getRequest());
			if (StrKit.isBlank(ip)) {
				ip = "127.0.0.1";
			}
			
			params.put("spbill_create_ip", ip);
			params.put("trade_type", TradeType.JSAPI.name());
			params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
			params.put("notify_url", notify_url);
			params.put("openid", openId);
	
			String sign = PaymentKit.createSign(params, paternerKey);
			params.put("sign", sign);
			String xmlResult = PaymentApi.pushOrder(params);
			
//			System.out.println(xmlResult);
			Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
			
			String return_code = result.get("return_code");
			String return_msg = result.get("return_msg");
			if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
				renderText(return_msg);
				return;
			}
			String result_code = result.get("result_code");
			if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
				renderText(return_msg);
				return;
			}
			// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
			String prepay_id = result.get("prepay_id");
			
			Map<String, String> packageParams = new HashMap<String, String>();
			packageParams.put("appId", appid);
			packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
			packageParams.put("nonceStr", System.currentTimeMillis() + "");
			packageParams.put("package", "prepay_id=" + prepay_id);
			packageParams.put("signType", "MD5");
			String packageSign = PaymentKit.createSign(packageParams, paternerKey);
			packageParams.put("paySign", packageSign);
			
			String phone = (String) getRequest().getSession().getAttribute("phone");
			String cardnum = (String) getRequest().getSession().getAttribute("cardnum");
			new Chongzhi().set("cardnum", cardnum)
							.set("phone", phone)
							.set("price", price)
							.set("openid", openId)
							.set("openid2", openid)
							.set("outTradeNo", out_trade_no)
							.save();
			String jsonStr = JsonUtils.toJson(packageParams);
			setAttr("json", jsonStr);
			render("pay.jsp");
		}
	}
	
	/**
	 * 支付回调
	 */
	public void pay_notify() {
		// 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
		String xmlMsg = HttpKit.readData(getRequest());
		Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
		String result_code  = params.get("result_code");
		// 总金额
		String totalFee     = params.get("total_fee");
		// 商户订单号
		String orderId      = params.get("out_trade_no");
		// 微信支付订单号
		String transId      = params.get("transaction_id");
		// 支付完成时间，格式为yyyyMMddHHmmss
		String timeEnd      = params.get("time_end");
		
		// 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
		// 避免已经成功、关闭、退款的订单被再次更新
		if(PaymentKit.verifyNotify(params, paternerKey)){
			if (("SUCCESS").equals(result_code)) {
				Chongzhi cz = Chongzhi.dao.findFirst("select id, iccid, cardnum, openid2, phone from chongzhi where outtradeno =? and state= ?", new Object[] { orderId, 0 });
				if(cz != null){
					//SIM卡充值回调
					if(orderId.substring(0, 3).equals("sim")){
						System.out.println("支付通知=" + xmlMsg);
						String iccid=cz.get("iccid");
						int price = Integer.parseInt(totalFee);
						price = price/100;
						int res = 0;//执行自动充值
						if(price >= 49){
							M2mController m2m = new M2mController();
							res = m2m.terminal(iccid);
							LogKit.warn("自动充值 状态:"+res);
						}else{
							LogKit.warn("测试充值:  price="+price);
						}
						//用户充值通知
						sendBLNews(iccid, price+"", res);
						TemplateController template = new TemplateController();
				      	template.paynotify(cz.get("openid2").toString(), iccid, price+"");
					}
					
					cz.set("timeend", timeEnd).set("state", 1).set("transactionid", transId).update();
				}
			}
		}
		renderText("");
	}
		
	public void sendBLNews(){
		renderJson(sendBLNews("111111111111111", "1", 1));
	}

	//BL操作通知
	public static ApiResult sendBLNews(String iccid, String price, int res){
		String title ="用户流量充值提醒：\niccid："+iccid
				+"\nmoney：￥"+price+"元"
				+"\nstatus： "+(res==1?"成功":"失败");
		return CustomServiceApi.sendText("oVKgLwvQsqpgbdPrSu74CE3NAGa8", title);//BL
	}
	
	public static ApiResult sendBLNews2(String cardnum, String price, int res){
		String title ="用户流量充值提醒：\n卡号："+cardnum
				+"\n金额：￥"+price+"元"
				+"\n状态： "+(res==1?"成功":"失败");
		return CustomServiceApi.sendText("oVKgLwvQsqpgbdPrSu74CE3NAGa8", title);//BL
	}

	
}

